#ifndef _BOUNDARY_H_
#define _BOUNDARY_H_

#include "defs.h"
#include "geometry.h"
#include "fluid.h"
#include "utility.hpp"
#include <vector>
class BoundConds
{
public:
  BoundConds() = default;
  BoundConds(const BoundConds &src) = delete;
  BoundConds(BoundConds &&src) = delete;
  BoundConds &operator=(const BoundConds &src) = delete;
  BoundConds &operator=(BoundConds &&src) = delete;
  ~BoundConds() = default;

  BoundConds(const Config &cfg, const Geometry &geo,
             Fluid &flow);
  // 暂时没有管 euler  若使用 euler 另设 farfieldEuler

  void WallNS(const BoundDescrp_t &Bdescrp);

  void WallEuler(const BoundDescrp_t &Bdescrp);

  void Symmetry(const BoundDescrp_t &Bdescrp);

  void BoundaryConditionsEuler(void);
  void BoundaryConditionsNS(void);
  template <typename T>
  void Farfield(const BoundDescrp_t &Bdescrp, const VarArray<T, 2, 0> &dv);
  void DependentVarsBoundaryEu(void);
  void DependentVarsBoundaryNS(void);

  const std::vector<BoundDescrp_t> &GetBoundaryDescrpAll(void) const
  {
    return Bdescrp;
  }

private:
  const Equation_t equsType;
  const std::vector<BoundDescrp_t> &Bdescrp;
  const VarArray<Area_t, 2, 0> &si, &sj;
  VarArray<ConsVar_t, 2, 0> &cv;
  VarArray<DeptVarE_t, 2, 0> &dvE;
  VarArray<DeptVarNS_t, 2, 0> &dvNS;
  VarArray<real_t, 2, 0> &press;
  const real_t ua, va, pa, rhoa, mach;

  const int
      il, //  !< index of the 1st dummy cell in i-direction (right side); il = imax - 1
      jl, //  !< index of the 1st dummy cell in j-direction (top side); jl = jmax - 1
      i2, //  !< index of the last physical cell in i-direction; i2 = imax - 2 (physical cells start at index 2)
      j2, // !< index of the last physical cell in j-direction; j2 = jmax - 2 (physical cells start at index 2)
      imax,
      jmax;
  CutExchg<ConsVar_t> cutExchgCV;
  CutExchg<DeptVarE_t> cutExchgDVE;
  CutExchg<DeptVarNS_t> cutExchgDVNS;
  CalcDependVarsOneEu calcDvOneEu;
  CalcDependVarsOneNS calcDvOneNS;
  void ExtraAtCorner(ConsVar_t &corner, const ConsVar_t &fir, const ConsVar_t &sec)
  {
    corner.rho = 0.5 * (fir.rho + sec.rho);
    corner.rhou = 0.5 * (fir.rhou + sec.rhou);
    corner.rhov = 0.5 * (fir.rhov + sec.rhov);
    corner.rhoE = 0.5 * (fir.rhoE + sec.rhoE);
  }
};

#endif